// 组件封装
// WangEditor.vue

<template>
  <div style="border: 1px solid #ccc" v-loading="loading" element-loading-text="文件上传中...">
    <!-- <div style="color: red; padding-left: 18px">注：视频最佳宽度700-900</div> -->
    <Toolbar
      style="border-bottom: 1px solid #ccc"
      class="count-yc-box-title"
      :editor="editorRef"
      :defaultConfig="toolbarConfig"
      :mode="mode"
    />

    <Editor
      style="min-height: 750px; overflow-y: auto"
      v-model="valueHtml"
      :defaultConfig="editorConfig"
      :mode="mode"
      @onCreated="handleCreated"
      class="count-yc-box"
    />
  </div>
</template>
<script>
//script标签中引入
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { defineExpose, onMounted, watch } from "vue";
import request from "@/utils/request"; // 这个是请求封装   请更换为你的地址
import { useRouter } from "vue-router"; // 引入 useRouter 函数

export default {
  components: { Editor, Toolbar },
  props: {
    editValue: {
      type: String,
      default: "",
    },
  },
  setup(props, { emit }) {
    const router = useRouter();
    emits: ["select"];
    // 编辑器实例，必须用 shallowRef
    const editorRef = shallowRef();
    console.log(editorRef, "editor.getAllMenuKeys()");
    // 内容 HTML
    const valueHtml = ref("");
    const loading = ref(false);

    watch(
      () => props.editValue,
      (val) => {
        //当编辑器的内容发生变化时，把值传给父组件
        valueHtml.value = props.editValue;
      },
      {
        deep: true,
        immediate: true,
      }
    );
    //配置功能栏
    let toolbarConfig = {
      toolbarKeys: [
        "headerSelect",
        "header1",
        "header2",
        "header3",
        {
          key: "group-video",
          title: "视频",
          iconSvg:
            '<svg viewBox="0 0 1024 1024"><path d="M981.184 160.096C837.568 139.456 678.848 128 512 128S186.432 139.456 42.816 160.096C15.296 267.808 0 386.848 0 512s15.264 244.16 42.816 351.904C186.464 884.544 345.152 896 512 896s325.568-11.456 469.184-32.096C1008.704 756.192 1024 637.152 1024 512s-15.264-244.16-42.816-351.904zM384 704V320l320 192-320 192z"></path></svg>',
          menuKeys: ["insertVideo", "uploadVideo"],
        },
        "blockquote",
        "|",
        "bold",
        "underline",
        "italic",
        "lineHeight",
        {
          key: "group-more-style",
          title: "更多",
          iconSvg:
            '<svg viewBox="0 0 1024 1024"><path d="M204.8 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path><path d="M505.6 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path><path d="M806.4 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path></svg>',
          menuKeys: ["through", "code", "sup", "sub"],
        },
        "color",
        "bgColor",
        "|",
        "fontSize",
        {
          key: "group-justify",
          title: "对齐",
          iconSvg:
            '<svg viewBox="0 0 1024 1024"><path d="M768 793.6v102.4H51.2v-102.4h716.8z m204.8-230.4v102.4H51.2v-102.4h921.6z m-204.8-230.4v102.4H51.2v-102.4h716.8zM972.8 102.4v102.4H51.2V102.4h921.6z"></path></svg>',
          menuKeys: [
            "justifyLeft",
            "justifyRight",
            "justifyCenter",
            "justifyJustify",
          ],
        },
        "todo",
        "fontFamily",
        {
          key: "group-indent",
          title: "缩进",
          iconSvg:
            '<svg viewBox="0 0 1024 1024"><path d="M0 64h1024v128H0z m384 192h640v128H384z m0 192h640v128H384z m0 192h640v128H384zM0 832h1024v128H0z m0-128V320l256 192z"></path></svg>',
          menuKeys: ["indent", "delIndent"],
        },

        "|",
        "emotion",
        "insertLink",
        "uploadImage",
        "insertTable",
        "codeBlock",
        "divider",
        "clearStyle",
        "|",
        "undo",
        "redo",
      ],
    };

    const uploadImageList = ref([]);
    const saveImageList = ref([]);

    //上传本地图片
    function update(file, insertFn) {
      let formData = new FormData();
      formData.append("file", file);
      loading.value = true;
      // request({
      //   url: "/common/file/upload",
      //   headers: {
      //     "Content-Type": "multipart/form-data",
      //   },
      //   method: "post",
      //   timeout: 50000,
      //   data: formData,
      // })
      //   .then((res) => {
      //     if (res.code === 200) {
      //       const src = res.data.fileUrl;
      //       insertFn(src, "百度 logo", src);
      //       loading.value = false;
      //     } else {
      //       loading.value = false;
      //     }
      //   })
      //   .catch(() => {
      //     loading.value = false;
      //   });
    }

    function getOnInsertedImage(imageNode) {
      uploadImageList.value.push(imageNode);
    }

    // 获取文件上传token
    const hasToken = localStorage.getItem("accessToken");
    const Headers = {
      Authorization: hasToken ? hasToken : "",
    };
    //编辑器配置
    let editorConfig = {
      placeholder: "请输入内容...",
      // 所有的菜单配置，都要在 MENU_CONF 属性下
      MENU_CONF: {
        insertImage: {
          onInsertedImage: getOnInsertedImage(),
        },
        // 配置上传图片
        uploadImage: {
          // customUpload: update,
          server: "https://xdcmt.com/oss/upload",
          // form-data fieldName ，默认值 'wangeditor-uploaded-image'
          fieldName: "file",
          // 单个文件的最大体积限制，默认为 2M
          maxFileSize: 1 * 1024 * 1024, // 1M
          // 最多可上传几个文件，默认为 100
          maxNumberOfFiles: 10,
          // 选择文件时的类型限制，默认为 ['image/*'] 。如不想限制，则设置为 []
          allowedFileTypes: ["image/*"],
          // 自定义上传参数，例如传递验证的 token 等。参数会被添加到 formData 中，一起上传到服务端。
          meta: {
            key: "firstPage",
            Bucket: "images",
          },
          // 将 meta 拼接到 url 参数中，默认 false
          metaWithUrl: false,
          // 自定义增加 http  header
          headers: Headers,
          // 跨域是否传递 cookie ，默认为 false
          withCredentials: false,
          // 超时时间，默认为 10 秒
          timeout: 5 * 1000, // 5 秒

          // 单个文件上传成功之后
          onSuccess(file, res) {
            // TS 语法
            // onSuccess(file, res) {          // JS 语法
            console.log(`${file.name} 上传成功`, res);
            if (res.code == 42011) {
              router.push("/login");
            }
          },

          onFailed(file, res) {
            if (res.code == 42011) {
              router.push("/login");
            }

            // TS 语法
            // onFailed(file, res) {           // JS 语法
            // console.log(`${file.name} 上传失败`, res);
            if (res.code == 20000) {
              valueHtml.value = `${valueHtml.value}<br/><img src="${res.data.url}"></img>`;
              console.log(valueHtml.value);
            }
          },

          // 上传错误，或者触发 timeout 超时
          onError(file, err, res) {
            if (res.code == 42011) {
              router.push("/login");
            }
            // TS 语法
            // onError(file, err, res) {               // JS 语法
            console.log(`${file.name} 上传出错`, err, res);
          },
        },
        uploadVideo: {
          customUpload: update,
        },
      },
    };

    // 组件销毁时，也及时销毁编辑器
    onBeforeUnmount(() => {
      const editor = editorRef.value;
      if (editor == null) return;
      editor.destroy();
    });

    function copyObject(obj) {
      return JSON.parse(JSON.stringify(obj));
    }
    const handleCreated = (editor) => {
      editorRef.value = editor; // 记录 editor 实例，重要！
      saveImageList.value = editor.getElemsByType("image");
      uploadImageList.value = copyObject(saveImageList.value);
    };

    watch(
      () => valueHtml.value,
      () => {
        //当编辑器的内容发生变化时，把值传给父组件
        emit("select", valueHtml.value);
      }
    );

    // 一下方法 用作回调 但暂时未调用
    const handleChange = (editor) => {
      console.log("change:", editor.children);
    };
    const handleDestroyed = (editor) => {
      console.log("destroyed", editor);
    };
    const handleFocus = (editor) => {
      console.log("focus", editor);
    };
    const handleBlur = (editor) => {
      console.log("blur", editor);
    };
    const customAlert = (info, type) => {
      console.log(`【自定义提示】${type} - ${info}`);
    };
    const customPaste = (editor, event, callback) => {
      console.log("ClipboardEvent 粘贴事件对象", event);
      // const html = event.clipboardData.getData('text/html') // 获取粘贴的 html
      // const text = event.clipboardData.getData('text/plain') // 获取粘贴的纯文本
      // const rtf = event.clipboardData.getData('text/rtf') // 获取 rtf 数据（如从 word wsp 复制粘贴）

      // 自定义插入内容
      editor.insertText("xxx");

      // 返回 false ，阻止默认粘贴行为
      event.preventDefault();
      callback(false); // 返回值（注意，vue 事件的返回值，不能用 return）

      // 返回 true ，继续默认的粘贴行为
      // callback(true)
    };

    //父组件调用子组件的方法清空编辑器内容
    const abc = function () {
      valueHtml.value = "";
    };
    //暴露该方法,defineExpose要引入
    defineExpose({
      abc,
      valueHtml,
    });

    return {
      editorRef,
      valueHtml,
      mode: "default", // 或 'simple'
      toolbarConfig,
      editorConfig,
      handleCreated,
      handleChange,
      handleDestroyed,
      handleFocus,
      handleBlur,
      customAlert,
      customPaste,
      abc,
      loading,
    };
  },
};
</script>

